﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using UCL.Powersource.Analysis;

namespace UCL.Powersource.Statistics
{
    /// <summary>
    /// Calculation of an accelaration of a stat in an iteration class
    /// </summary>
    [Export(typeof(IStatistic))]
    [DataContract(IsReference = true)]
    public class AccelerationStatistics : EffortStatisticsBase
    {
        [ExcludeFromCodeCoverage]
        public override string Label
        {
            get { return "Acceleration"; }
        }

        [ExcludeFromCodeCoverage]
        public override string Description
        {
            get { return "Acceleration of a stat in an iteration"; }
        }

        [ExcludeFromCodeCoverage]
        public override string Name
        {
            get { return "Acceleration"; }
        }

        public static readonly Guid CN_Statistic_Guid = new Guid("FCCB01D1-6494-434F-8550-F47A3CE19ED5");
        [ExcludeFromCodeCoverage]
        public override Guid Statistic_Guid
            
        {
            get { return CN_Statistic_Guid; }
        }

        [DataMember]
        private readonly string _QueryString = "Select [ID], [Iteration Path], [State], [Effort] From WorkItems Where [Work Item Type] = 'Product Backlog Item'";       // Declaration of the _QueryString which returns work item ID, iteration path, state and effort

        protected override string QueryString { get { return _QueryString; } }

        [DataMember]
        private readonly string _WIType = "";

        protected override string WIType { get { return _WIType; } }

        [DataMember]
        private readonly string _State = "Done";

        protected override string State { get { return _State; } }

        [DataMember]
        private readonly string _WasEver = "";

        protected override string WasEver { get { return _WasEver; } }

        [DataMember]
        private string _FormatString = "0.00";

        public override string FormatString
        {
            get
            {
                return _FormatString;
            }
        }

        protected override bool ValidState(WorkItem item)
        {
            return (string)item.Fields["State"].Value == State;
        }

        /// <summary>
        /// Class for accelaration calculation
        /// </summary>
        /// <param name="teamProjConfig">Tfs stat project configuration</param>
        /// <param name="timeFrame">Work item time frame</param>
        /// <param name="qString">Work item query string</param>
        /// <returns>The value of accelaration</returns>
        protected override double? CalculateStatistic(ITfsTeamProjectConfiguration teamProjConfig, ITimeFrame timeFrame, string qString)
        {
            double? current = base.CalculateStatistic(teamProjConfig, timeFrame, qString);
            ITimeFrameIteration timeframe = (ITimeFrameIteration)timeFrame;
            foreach (ITimeFrameIteration frame in teamProjConfig.ProjectTimeframes)
            {
                if (frame.FinishDate < timeframe.FinishDate && frame.TimeFrameType==timeFrame.TimeFrameType) timeframe = frame;
            }
            double? first = base.CalculateStatistic(teamProjConfig, timeframe, qString);

            if (first == 0)
            {
                Log.Error(new ArgumentException(), "Acceleration cannot be calculated, devision by 0 not possible. Velocity for first iteration is 0 for project {0}", teamProjConfig.UniqueName);
                return null;
            }
            if (current == null || first == null)
            {
                Log.Error(new ArgumentException(), "Acceleration cannot be calculated, null velocity value for iteration for project {0}", teamProjConfig.UniqueName);
                return null;
            }
            
            return (current - first) / first;
        } 
    }
}
